package xcmg.device.service.agent;

import com.github.pagehelper.PageInfo;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xcmg.device.dao.entity.agent.ServiceBorrowOutDO;
import xcmg.device.dao.entity.agent.ServiceBorrowOutDetailDO;
import xcmg.device.dao.entity.warehouse.WarehouseDeliveryDetailDO;
import xcmg.device.dao.mapper.agent.ServiceBorrowOutDetailMapper;
import xcmg.device.dao.mapper.agent.ServiceBorrowOutMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryDetailMapper;
import xcmg.device.dao.mapper.warehouse.WarehouseDeliveryMapper;
import xcmg.device.infra.ErrorCode;
import xcmg.device.infra.FileUtil;
import xcmg.device.infra.ImportUtil;
import xcmg.device.service.basic.MaterialsService;
import xcmg.device.service.vo.FunctionResult;
import xcmg.device.service.vo.agent.ServiceBorrowOutDetailVO;
import xcmg.device.service.vo.agent.ServiceBorrowOutVO;
import xcmg.device.service.vo.basic.MaterialLocationRelationVO;
import xcmg.device.service.vo.basic.MaterialsVO;
import xcmg.device.service.vo.warehouse.app.EnableAndOccupyVO;
import xcmg.device.service.warehouse.WarehouseDeliveryService;
import xcmg.device.service.warehouse.WarehouseInventoryService;
import yb.ecp.fast.feign.FastGenClient;
import yb.ecp.fast.infra.infra.ActionResult;
import yb.ecp.fast.infra.infra.PageCommonVO;
import yb.ecp.fast.infra.infra.SearchCommonVO;
import yb.ecp.fast.infra.util.ListUtil;
import yb.ecp.fast.infra.util.PageHelperPlus;
import yb.ecp.fast.infra.util.StringUtil;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * ServiceBorrowOutDetail 后台接口实现类
 *
 * @author huhuawei
 */
@Service
public class ServiceBorrowOutDetailService {

    private static final Logger logger = LoggerFactory.getLogger(ServiceBorrowOutDetailService.class);

    @Autowired
    private ServiceBorrowOutDetailMapper serviceBorrowOutDetailMapper;

    @Autowired
    private FastGenClient fastGenClient;
    @Autowired
    private ServiceBorrowOutMapper serviceBorrowOutMapper;

    @Autowired
    private WarehouseDeliveryService warehouseDeliveryService;

    @Autowired
    private MaterialsService materialsService;

    @Autowired
    private WarehouseInventoryService warehouseInventoryService;

    @Autowired
    private WarehouseDeliveryMapper warehouseDeliveryMapper;

    @Autowired
    private WarehouseDeliveryDetailMapper warehouseDeliveryDetailMapper;

    @Autowired
    private HttpServletResponse response;
    @Autowired
    private ServiceStaffQuotaService serviceStaffQuotaService;

    @Value("${spring.file.download.path}")
    private String filePath;
    private String templateExcelFileName = "BorrowOutImport.xls";

    /**
     * 查询列表
     *
     * @param condition
     */
    public PageCommonVO<ServiceBorrowOutDetailVO> list(SearchCommonVO<ServiceBorrowOutDetailVO> condition) {
        if (null == condition.getFilters()) {
            condition.setFilters(new ServiceBorrowOutDetailVO());
        }
        PageCommonVO<ServiceBorrowOutDetailVO> pageCommonVO = new PageCommonVO();
        PageHelperPlus.orderBy("create_date desc");
        PageHelperPlus.startPage(condition.getPageNum(), condition.getPageSize());
        List<ServiceBorrowOutDetailDO> queryList = serviceBorrowOutDetailMapper.queryList(condition.getFilters());
        List<ServiceBorrowOutDetailVO> voList = new ArrayList<ServiceBorrowOutDetailVO>();
        for (ServiceBorrowOutDetailDO entity : queryList) {
            ServiceBorrowOutDetailVO serviceBorrowOutDetailVO = new ServiceBorrowOutDetailVO();
            BeanUtils.copyProperties(entity, serviceBorrowOutDetailVO);
            voList.add(serviceBorrowOutDetailVO);
        }
        pageCommonVO.setPageInfo(new PageInfo(queryList));
        pageCommonVO.setPageInfoList(voList);
        return pageCommonVO;
    }

    /**
     * 查询列表
     *
     * @param vo
     */
    public List<ServiceBorrowOutDetailDO> queryList(ServiceBorrowOutDetailVO vo) {
        return serviceBorrowOutDetailMapper.queryList(vo);
    }


    /**
     * 查询单条记录
     *
     * @param id
     */
    public ServiceBorrowOutDetailDO queryById(String id) {
        ServiceBorrowOutDetailVO vo = new ServiceBorrowOutDetailVO();
        vo.setId(id);
        List<ServiceBorrowOutDetailDO> list = queryList(vo);
        if (CollectionUtils.isNotEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    /**
     * 查询详情根据服务人员id
     * @param serviceUserId
     * @return
     */
    public List<ServiceBorrowOutDetailDO> queryByServiceUserId(String serviceUserId,String materialsNo,String orgId,String id) {
        return serviceBorrowOutDetailMapper.queryByServiceUserId(serviceUserId,materialsNo,orgId,id);
    }


    /**
     * 保存数据
     *
     * @param serviceBorrowOutDetailVO
     * @param userId
     * @param userName
     * @param orgId
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode save(ServiceBorrowOutDetailVO serviceBorrowOutDetailVO, String userId, String userName, String orgId) throws Exception {
        return doSave(serviceBorrowOutDetailVO, userId, userName, orgId);
    }

    /**
     * 根据状态，等信息保存数据
     *
     * @param outDetailVO
     * @param userId
     * @param userName
     * @param orgId
     */
    private ErrorCode doSave(ServiceBorrowOutDetailVO outDetailVO, String userId, String userName, String orgId) throws Exception {
        preSaveCheck(outDetailVO);
        ServiceBorrowOutDetailDO outDetailDO = new ServiceBorrowOutDetailDO();
        ActionResult<String> textResult = fastGenClient.textGuid();
        if (textResult.getCode() != ErrorCode.Success.getCode()) {
            return ErrorCode.IllegalArument;
        }
        boolean isSuccess = false;
        if (StringUtils.isBlank(outDetailVO.getId())) {
            BeanUtils.copyProperties(outDetailVO, outDetailDO);
            outDetailDO.setId(textResult.getValue());
            // 0-未出库，1-部分出库，2-已出库，3-结单
            //新增的时候需要保存状态 默认出库数量为0
            outDetailDO.setStatus(0);
            outDetailDO.setOutQuantity(new BigDecimal(0));
            isSuccess = this.merge(outDetailDO) > 0;
            logger.info("新增操作，serviceBorrowOutDetailDO:{}", outDetailDO);
            //新增的时候与主表一起生产出库基表

        } else {
            outDetailDO.setId(outDetailVO.getId());
            outDetailDO.setQuantity(outDetailVO.getQuantity());
            outDetailDO.setStatus(outDetailVO.getStatus());
            outDetailDO.setCostPrice(outDetailVO.getCostPrice());
            outDetailDO.setCostSubtotal(outDetailVO.getCostSubtotal());
            outDetailDO.setSubtotalAmount(outDetailVO.getSubtotalAmount());
            logger.info("编辑操作，serviceBorrowOutDetailDO:{}", outDetailDO);
            isSuccess = serviceBorrowOutDetailMapper.updateByPrimaryKeySelective(outDetailDO) > 0;

            //更新出库基表的数量和状态
            ErrorCode errorCode = warehouseDeliveryService.updateDetailState(outDetailVO.getBorrowOutNo(),
                    outDetailVO.getMaterialsNo(), outDetailDO.getQuantity(), outDetailDO.getStatus(), orgId);
            if (errorCode.getCode() != 0) {
                throw new Exception("更新出库事物单详情记录失败");
            }

        }
        if (!isSuccess) {
            return ErrorCode.Failure;
        }
        return ErrorCode.Success;
    }
    
    public void deleteByBorrowOutId(String borrowOutId) {
        serviceBorrowOutDetailMapper.deleteByBorrowId(borrowOutId);
    }
    
    public void syncDetail(ServiceBorrowOutDetailVO outDetailVO) throws Exception {
        preSaveCheck(outDetailVO);
        ServiceBorrowOutDetailDO outDetailDO = new ServiceBorrowOutDetailDO();
        ActionResult<String> textResult = fastGenClient.textGuid();
        if (textResult.getCode() != ErrorCode.Success.getCode()) {
            throw new Exception(ErrorCode.IllegalArument.getDesc());
        }
        boolean isSuccess = false;
        if (StringUtils.isBlank(outDetailVO.getId())) {
            BeanUtils.copyProperties(outDetailVO, outDetailDO);
            outDetailDO.setId(textResult.getValue());
            // 0-未出库，1-部分出库，2-已出库，3-结单
            //新增的时候需要保存状态
            outDetailDO.setStatus(0);
            //outDetailDO.setOutQuantity(new BigDecimal(0));
            isSuccess = serviceBorrowOutDetailMapper.merge(outDetailDO) > 0;
            logger.info("新增操作，serviceBorrowOutDetailDO:{}", outDetailDO);
            //新增的时候与主表一起生产出库基表

        }
        if (!isSuccess) {
            throw new Exception(ErrorCode.Failure.getDesc());
        }
    }

    /**
     * 保存前信息校验
     */
    private void preSaveCheck(ServiceBorrowOutDetailVO serviceBorrowOutDetailVO) throws Exception {
        if (null == serviceBorrowOutDetailVO) {
            throw new Exception(ErrorCode.IllegalArument.getDesc());
        }
        //TODO如果是提交操作或者某些状态下需要做校验吗？
        //        if (isSubmit&&status？？？) {
        //        }
        //TODO 如果是编辑,需要做的校验 。。。
        if (StringUtils.isNotBlank(serviceBorrowOutDetailVO.getId())) {
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public int merge(ServiceBorrowOutDetailDO dto) {
        return serviceBorrowOutDetailMapper.merge(dto);
    }

    /**
     * 批量删除
     *
     * @param ids
     */
    @Transactional(rollbackFor = Exception.class)
    public ErrorCode batchDelete(List<String> ids) throws Exception {
        if (CollectionUtils.isEmpty(ids)) {
            return ErrorCode.Failure;
        }
        for (String id : ids) {
            int i = serviceBorrowOutDetailMapper.deleteByPrimaryKeySelective(id);
//            if (i == 0) {
//                throw new Exception(ErrorCode.Failure.getDesc());
//            }
        }
        return ErrorCode.Success;
    }

    /**
     * @Author: WangKe
     * @Description: 下载零件批量导入模板
     * @Date: 2018/3/1 0001
     */
    public void download() throws Exception {
        FileUtil.downLoadFile(response, filePath, templateExcelFileName);
    }


    /**
     * @Author: WangKe
     * @Description: 零件批量导入
     * @Date: 2018/3/1 0001
     */
    public FunctionResult importExcel(InputStream in, String warehouseCode, String areaCode, String orgId) throws Exception {
        FunctionResult result = new FunctionResult();
        HSSFWorkbook wb = new HSSFWorkbook(in);
        HSSFSheet sheet = wb.getSheetAt(0);

        int totalRow = sheet.getLastRowNum();
        if (totalRow < 2) {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        int totalCell = sheet.getRow(1).getLastCellNum();
        if (totalCell != 5) {
            result.setCode(ErrorCode.IllegalArument);
            result.setValue("导入模板不正确");
            return result;
        }
        List<ServiceBorrowOutDetailVO> detailVOList = new ArrayList<>();
        List<ServiceBorrowOutDetailVO> errorDetailVOList = new ArrayList<>();
        MaterialLocationRelationVO relationVO = new MaterialLocationRelationVO();
        EnableAndOccupyVO enableAndOccupyVO;
        for (int i = 2; i <= totalRow; i++) {
            HSSFRow curRow = sheet.getRow(i);
            ServiceBorrowOutDetailVO detailVO = new ServiceBorrowOutDetailVO();
            if (curRow == null) {
                continue;
            }
            String no = getCellValue(curRow, 0);
            String materialsNo = getCellValue(curRow, 1);
            String qty = getCellValue(curRow, 4);
            if (StringUtil.isNullOrEmpty(no) && StringUtil.isNullOrEmpty(materialsNo) && StringUtil.isNullOrEmpty(qty)) {
                continue;
            }
           /* if(StringUtil.isNullOrEmpty(no)){
                detailVO.setErrorRow(i+1);
                detailVO.setRemark("序号不能为空");
                errorDetailVOList.add(detailVO);
                continue;
            }*/
            if (StringUtil.isNullOrEmpty(materialsNo)) {
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark("零件编码不能为空");
                errorDetailVOList.add(detailVO);
                continue;
            }
            if (StringUtil.isNullOrEmpty(qty)) {
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark("借用数量不能为空");
                errorDetailVOList.add(detailVO);
                continue;
            }
            if (!isInteger(qty) || "0".equals(qty)) {
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark("借用数量格式不正确");
                errorDetailVOList.add(detailVO);
                continue;
            }
            if (new BigDecimal(qty).compareTo(BigDecimal.valueOf(99999999.99)) > 0) {
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark("借用数量过大");
                errorDetailVOList.add(detailVO);
                continue;
            }
            MaterialsVO materialsVO = materialsService.itemByNo(materialsNo, orgId);
            if (materialsVO == null) {
                detailVO.setErrorRow(i + 1);
                detailVO.setRemark("零件不存在");
                errorDetailVOList.add(detailVO);
                continue;
            }
            detailVO.setQuantity(new BigDecimal(qty));
            detailVO.setMaterialsNo(materialsVO.getMaterialsNo());
            detailVO.setMaterialsDes(materialsVO.getMaterialsDes());
//            detailVO.setMaterialsType(materialsVO.getMaterialsType());
            detailVO.setUnit(materialsVO.getUnit());
            detailVO.setPrice(materialsVO.getPrice());
            detailVO.setSubtotalAmount(detailVO.getPrice() == null ? new BigDecimal(0) : detailVO.getPrice()
                    .multiply(detailVO.getQuantity()));
            detailVO.setCostPrice(materialsVO.getStandardPrice());
            detailVO.setCostSubtotal(detailVO.getCostPrice() == null ? new BigDecimal(0) : detailVO.getCostPrice()
                    .multiply(detailVO.getQuantity()));

            relationVO.setOrgId(orgId);
            relationVO.setMaterialNo(materialsVO.getMaterialsNo());
            relationVO.setWarehouseCode(warehouseCode);
            relationVO.setAreaCode(areaCode);
//            detailVO.setLocationCode(materialLocationRelationMapper.findLocationCode(relationVO));
            enableAndOccupyVO = warehouseInventoryService.findEnableAndOccupyNum(detailVO.getMaterialsNo(), orgId, warehouseCode);
            BeanUtils.copyProperties(enableAndOccupyVO, detailVO);
            detailVOList.add(detailVO);
        }

        if (ListUtil.isNullOrEmpty(errorDetailVOList)) {
            result.setValue(ImportUtil.deRepeat(detailVOList, "MaterialsNo", "Quantity", null, null));
            result.setCode(ErrorCode.Success);
        } else {
            result.setValue(errorDetailVOList);
            result.setCode(ErrorCode.IllegalArument);
        }
        return result;
    }

    private boolean isInteger(String str) {
        if (null == str || "".equals(str)) {
            return false;
        }
        try {
            BigDecimal decimal = new BigDecimal(str);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    private String getCellValue(HSSFRow curRow, int i) {
        String value = "";
        if (curRow.getCell(i) != null) {
            curRow.getCell(i).setCellType(CellType.STRING);
            value = curRow.getCell(i).getStringCellValue();
        }
        return value;
    }


    @Transactional(rollbackFor = Exception.class)
    public ErrorCode delete(List<String> ids, String orgId) throws Exception {
        Map<String, ServiceBorrowOutDO> serviceBorrowInDOTemp = new HashMap<>();
        for (String id : ids) {
            ServiceBorrowOutDetailDO serviceBorrowOutDetailDO = serviceBorrowOutDetailMapper.selectByPrimaryKey(id);
            if (null == serviceBorrowOutDetailDO || serviceBorrowOutDetailDO.getStatus() != 0) {
                throw new Exception(ErrorCode.Failure.getDesc());
            }

            ServiceBorrowOutDO borrowOutDO = serviceBorrowInDOTemp.get("borrowOutDO");
            if (borrowOutDO == null) {
                ServiceBorrowOutVO condition = new ServiceBorrowOutVO();
                condition.setId(serviceBorrowOutDetailDO.getBorrowOutId());
                List<ServiceBorrowOutDO> serviceBorrowOutDOList = serviceBorrowOutMapper.queryList(condition);
                serviceBorrowInDOTemp.put("borrowOutDO", serviceBorrowOutDOList.get(0));
            }

            //删除事物
            removeByBusinessOrders(orgId, serviceBorrowOutDetailDO, serviceBorrowInDOTemp.get("borrowOutDO"));
            //删除详情表
            int delCount = serviceBorrowOutDetailMapper.deleteByPrimaryKeySelective(id);
            if (delCount <= 0) {
                throw new Exception(ErrorCode.Failure.getDesc());
            }
        }

        return ErrorCode.Success;
    }

    private void removeByBusinessOrders(String orgId, ServiceBorrowOutDetailDO serviceBorrowOutDetailDO, ServiceBorrowOutDO serviceBorrowOutDO) throws Exception {
        String materialsNo = serviceBorrowOutDetailDO.getMaterialsNo();
        String borrowNo = serviceBorrowOutDO.getBorrowNo();
        WarehouseDeliveryDetailDO record = new WarehouseDeliveryDetailDO();
        record.setBusinessOrder(borrowNo);
        record.setMaterialNo(materialsNo);
        record.setOrgId(orgId);
        int delCount = warehouseDeliveryDetailMapper.deleteByMaterial(record);
        if (delCount <= 0) {
            throw new Exception(ErrorCode.Failure.getDesc());
        }
    }
}
